package net.lovesrc.support.service.lock;

import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.TimeUnit;

public class RedisTemplateDistributedLock implements DistributedLock {

    private final RedisTemplate redisTemplate;

    public RedisTemplateDistributedLock(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public void lock(String key) {
        for (int i = 0; i < 10000; i++) {
            if (tryLock(key)) {
                return;
            }
        }
    }

    @Override
    public boolean lock(String key, long timeout, TimeUnit timeUnit) {
        long start = System.currentTimeMillis();
        long end = start + timeUnit.toMillis(timeout);
        for (; ; ) {
            if (System.currentTimeMillis() > end) {
                return false;
            }
            if (tryLock(key)) {
                return true;
            }
        }
    }

    @Override
    public void unlock(String key) {
        redisTemplate.delete(PREFIX + key);
    }

    @Override
    public boolean tryLock(String key) {
        return redisTemplate.opsForValue().setIfAbsent(PREFIX + key, System.currentTimeMillis());
    }

}
